#include "my_app_power.h"

// DC
#define APP_DC_PORT GPIOA
#define APP_DC_PIN LL_GPIO_PIN_7
#define APP_DC_PIN_ReadLevel() LL_GPIO_IsInputPinSet(APP_DC_PORT, APP_DC_PIN)

// BAT
#define APP_BAT_PORT GPIOA
#define APP_BAT_PIN LL_GPIO_PIN_5

#define BAT_ADC_INTERVAL (1 * 1000) // (60 * 1000) // 电池供电情况下 每分钟检测一次电量
#define DC_ADC_INTERVAL (1 * 1000)  // DC供电情况下 每10秒检测一次电量

#define MV_MAX 6800
#define MV_MIN 3800

#define BAT_LOW_ALARM_MV 4300
#define BAT_OFF_MV 3900

void my_app_power_init(void)
{
    app_dc_init();
    if (RESET == APP_DC_PIN_ReadLevel())
        dev_obj->type = BAT_TYPE;
    else
        dev_obj->type = DC_TYPE;
}

void my_app_power_task(void)
{
    app_power_battery_read();
}

void app_dc_init(void)
{
    LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
    LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
    LL_EXTI_InitTypeDef EXTI_InitStruct = {0};

    GPIO_InitStruct.Pin = APP_DC_PIN;
    GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    LL_GPIO_Init(APP_DC_PORT, &GPIO_InitStruct);

    EXTI_InitStruct.Line = LL_EXTI_LINE_7;
    EXTI_InitStruct.LineCommand = ENABLE;
    EXTI_InitStruct.Mode = LL_EXTI_MODE_IT_EVENT;
    EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING_FALLING;
    LL_EXTI_Init(&EXTI_InitStruct);

    LL_EXTI_SetEXTISource(LL_EXTI_CONFIG_PORTA, LL_EXTI_CONFIG_LINE7);
    NVIC_SetPriority(EXTI4_15_IRQn, 5);
    NVIC_EnableIRQ(EXTI4_15_IRQn);
}

void app_power_battery_read(void)
{
    static unsigned int last_time = 0;
    static unsigned char notify_bat = 0;    
    unsigned int interval = dev_obj->type == DC_TYPE ? DC_ADC_INTERVAL : BAT_ADC_INTERVAL;

    if (time_after(app_sys_ticks, last_time + interval) && app_release_is_ok())
    {
        last_time = app_sys_ticks;
        dev_obj->battery = app_adc_convert(LL_ADC_CHANNEL_5);

        dp_obj->bat = (unsigned char)((dev_obj->battery * 3300 / 4095.0 * 2 - MV_MIN) / (float)(MV_MAX - MV_MIN) * 100); // 百分比

        sg_alarm_mgr.real_bat = (unsigned int)(dev_obj->battery * 3300 / 4095.0 * 2); // 实时电压   单位mv

        if (sg_alarm_mgr.real_bat <= BAT_LOW_ALARM_MV)
            app_set_alarm_bat_low(1);
        else if (sg_alarm_mgr.real_bat >= BAT_LOW_ALARM_MV + 100)
        {
            app_set_alarm_bat_low(0);
        }

        if (sg_alarm_mgr.real_bat <= BAT_OFF_MV && dev_obj->type == BAT_TYPE)
        {
            sg_alarm_mgr.bat_off = 1;
            if (sg_burn_mgr.state == 1) //正在老化
            {
                sg_burn_mgr.state = 0;  //推出老化
                app_motor_stop();
            }
            //if (sg_menu.state == MENU_BAT_LOCK || sg_menu.state == MENU_BAT_LOCK_STANDBY || sg_menu.state == MENU_TIP || sg_menu.state == MENU_STANDBY) return ;
            //app_set_menu_led(MENU_BAT_LOCK_STANDBY);
        }
        else if (sg_alarm_mgr.real_bat >= BAT_OFF_MV + 100 || dev_obj->type == DC_TYPE)
        {
            sg_alarm_mgr.bat_off = 0;
        }
        if (dev_obj->tuya_net == TUYA_NET_OK)   // 网络正常 
        {
            if (dp_obj->bat - notify_bat >= 10 || notify_bat - dp_obj->bat >= 10)
            {
                notify_bat = dp_obj->bat;
                app_dp_bat_notify(); 
            }
        }
    }
}

void app_power_irq_handler(void)
{
    if (RESET == APP_DC_PIN_ReadLevel())
    {
        dev_obj->type = BAT_TYPE;
    }
    else
    {
        dev_obj->type = DC_TYPE;
    }
}
